<!DOCTYPE html>
<html lang="en">
<head>
    <title>Scanner.js demo: scan and recognize barcodes</title>
    <meta charset='utf-8'>
	<meta name="keywords" content="ScannerJs JavaScript document scanner scan and recognize barcodes CODE 128 EAN 8 13 UPC Code 3 of 9 code interleaved 2 of 5 QR PDF DataMatrix Data Matrix reader">
    <script src="https://asprise.azureedge.net/scannerjs/scanner.js" type="text/javascript"></script>

    <script>
        //
        // Please read scanner.js developer's guide at: http://asprise.com/document-scan-upload-image-browser/ie-chrome-firefox-scanner-docs.html
        //

        // default barcode area: full page
        var areaX = 0, areaY = 0, areaWidth = 1, areaHeight = 1;

        /**
         * One or more areas for barcode recognition
         * @return {[null]}
         */
        function getBarcodeAreas() {
            return [
                [areaX, areaY, areaWidth, areaHeight] // Scanner.js support multiple areas. This demo uses only one.
            ];
        }

        function scanAndReadBarcodeDefault() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
					"recognize_barcodes": true, /** Default value: false */
					"barcodes_settings": [
						{
							"type": "default",
                            "areas": getBarcodeAreas()
						}
					],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        function scanAndReadBarcodeMethod2Fast() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
                    "recognize_barcodes": true, /** Default value: false */
                "barcodes_settings": [
                    {
                        "type": "ALL",
                        "areas": getBarcodeAreas()
                    }
                ],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        function scanAndReadBarcodeMethod2Accurate() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
                    "recognize_barcodes": true, /** Default value: false */
                    "barcodes_settings": [
                    {
                        "type": "ALL, Accurate",
                        "areas": getBarcodeAreas()
                    }
                ],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        function scanAndReadBarcodeMethod2Code39AndCode128() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
                    "recognize_barcodes": true, /** Default value: false */
                "barcodes_settings": [
                    {
                        "type": "CODE39, CODE128, Accurate",
                        "areas": getBarcodeAreas()
                    }
                ],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        function scanAndReadBarcodeDataMatrix() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
                    "recognize_barcodes": true, /** Default value: false */
                    "barcodes_settings": [
                    {
                        "type": "dmtx",
                        "areas": getBarcodeAreas()
                    }
                ],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        function scanAndReadQr() {
            scanner.scan(displayImagesOnPageAndGetBarcodes,
                {
                    "recognize_barcodes": true, /** Default value: false */
                "barcodes_settings": [
                    {
                        "type": "QR",
                        "areas": getBarcodeAreas()
                    }
                ],
                    "output_settings": [
                        {
                            "type": "return-base64",
                            "format": "jpg"
                        }
                    ]
                }
            );
        }

        /** Processes the scan result */
        function displayImagesOnPageAndGetBarcodes(successful, mesg, response) {
            if(!successful) { // On error
                console.error('Failed: ' + mesg);
                return;
            }

            if(successful && mesg != null && mesg.toLowerCase().indexOf('user cancel') >= 0) { // User cancelled.
                console.info('User cancelled');
                return;
            }

            var scannedImages = scanner.getScannedImages(response, true, false); // returns an array of ScannedImage
            for(var i = 0; (scannedImages instanceof Array) && i < scannedImages.length; i++) {
                var scannedImage = scannedImages[i];
                processScannedImage(scannedImage);
            }
        }

        /** Images scanned so far. */
        var imagesScanned = [];

        /** Processes a ScannedImage */
        function processScannedImage(scannedImage) {
			var info = scannedImage.getInfo();
			console.log(info);
			
			var barcodes = info.barcodes;
			var barcodesText = "No. of barcodes found: " + (Array.isArray(barcodes) ? barcodes.length : 0);
			for(var b = 0; Array.isArray(barcodes) && b < barcodes.length; b++) {
				barcodesText += b == 0 ? " → " : "; ";
				barcodesText += barcodes[b].data + " (" + barcodes[b].type + ")";
			}
		
            imagesScanned.push(scannedImage);
            var elementPage = scanner.createDomElementFromModel({
                'name': 'div',
                'attributes': {
                    'class': 'page'
                },
				'children': [
					{
						'name': 'img',
						'attributes': {
							'class': 'scanned zoom',
							'title': scannedImage.toString(),
							'src': scannedImage.src
						}
					},
					{
						'name': 'p',
						'attributes': {
							'class': 'barcodeInfo',
							'text': barcodesText
						}
					}
				]
			});
            document.getElementById('images').appendChild(elementPage);

            enableZoom();
        }

    </script>

    <style>
        div#images {
            margin-top: 16px;
        }
		
		div#images div.page img.scanned {
			max-width: 100px;
		}

        div#images div.page {
            border-bottom: solid 1px #999;
            margin-bottom: 12px;
        }

        div.buttons div {
            margin-top: 12px;
        }

        div.values {
            margin-top: 20px;
        }
        div.values span.value {
            font-family: "Courier New", "Courier", "mono";
            font-weight: bold;
            font-size: 18px;
        }
        div.values p {
            font-size: 14px;
            margin-bottom: 6px;
        }
    </style>

</head>
<body>


<div class="container" style="margin: 20px auto;">
    <div class="row">
    <div class="col">
        <h2>Scanner.js: scan and recognize barcodes</h2>
    </div>
    </div>
    <div class="row">
        <div class="col-5">
            <h4>Barcode Areas</h4>
            <div class="row">
                <div class="col cropregion">
                    <div class="crop-container" style="">
                        <div id="img-container" style="max-width: 400px; margin: 0px auto;">
                            <img id="image" style="max-height: 200px; max-width: 200px;" src="">
                        </div>
                            <button type="button" id="replace" class="btn btn-sm btn-primary" style="font-size: 12px; position: absolute; right: 8px; margin-top: 12px;">Replace Image</button>
                        <div>
                            <input type="file" id="browse" style="display: none;" name="myImage" accept="image/*" />
                        </div>
                    </div>
                    <div class="values">
                        <p style="margin-bottom: 0; padding-bottom: 0">X: <span class="value value-x"></span>, Y: <span class="value value-y"></span>, Width: <span class="value value-w"></span>, Height: <span class="value value-h"></span>
                        <a href="javascript:selectFullPage();">Full</a>
                        </p>
                        <p style='font-family: "Courier New", "Courier", "mono"; font-size: 18px; '>[<span class="value-x"></span>, <span class="value-y"></span>, <span class="value-w"></span>, <span class="value-h"></span>]</p>

                    </div>
                </div>
            </div>
            <p style="color: #888;">By default, Scanner.js will search the full image. You may speed up the process by specifying regions.
            x/width and y/height are in percentage of the image width and height respectively.</p>
        </div>
        <div class="col-7">
            <div class="buttons">
                <div>
                    <button type="button" onclick="scanAndReadBarcodeDefault();" class="btn btn-primary">Scan and read barcodes &amp; QR (Default method)</button> &nbsp;&nbsp;
                </div>
                <div>
                    <button type="button" onclick="scanAndReadBarcodeMethod2Fast();" class="btn btn-primary">Scan and read barcodes &amp; QR (Method 2: fast mode)</button>
                </div>
                <div>
                    <button type="button" onclick="scanAndReadBarcodeMethod2Accurate();" class="btn btn-primary">Scan and read barcodes &amp; QR (Method 2: accurate)</button>
                </div>
                <div>
                    <button type="button" onclick="scanAndReadBarcodeMethod2Code39AndCode128();" class="btn btn-primary">Scan and read Code 38 &amp; 128 only (Method 2)</button>
                </div>
                <div>
                    <button type="button" onclick="scanAndReadBarcodeDataMatrix();" class="btn btn-primary">Scan and read data matrix</button>
                </div>
                <div>
                    <button type="button" onclick="scanAndReadQr();" class="btn btn-primary">Scan and read QR codes</button>
                </div>
            </div>

        </div>
    </div>

    <div class="row">
        <div class="col">
            <div id="images"></div>
        </div>
    </div>

    <div class="row">
        <div class="col">

    <!-- HELP_LINKS_START help links at the bottom -->
    <style>
        .asprise-footer, .asprise-footer a:visited { font-family: Arial, Helvetica, sans-serif; color: #999; font-size: 13px; }
        .asprise-footer a {  text-decoration: none; color: #999; }
        .asprise-footer a:hover {  padding-bottom: 2px; border-bottom: solid 1px #9cd; color: #06c; }
    </style>
    <div class="asprise-footer" style="margin-top: 48px;">
        <a href="http://asprise.com/document-scan-upload-image-browser/direct-to-server-php-asp.net-overview.html" target="_blank" title="Opens in new tab">Scanner.js Homepage</a> |
        <a href="http://asprise.com/scan/scannerjs/docs/html/scannerjs-javascript-guide.html" target="_blank" title="Opens in new tab">Developer's Guide to ScannerJs</a> |
        <a href="https://github.com/Asprise/scannerjs.javascript-scanner-access-in-browsers-chrome-ie.scanner.js" target="_blank" title="Opens in new tab">Sample code on Github</a>
    </div>
    <!-- HELP_LINKS_END -->

        </div>
    </div>
</div>



<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" ></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" ></script>

<!-- required by https://fengyuanchen.github.io/cropperjs/ -->
<!--<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>-->
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js"></script>-->
<script src="https://fengyuanchen.github.io/cropperjs/js/cropper.js"></script>
<link rel="stylesheet" href="https://fengyuanchen.github.io/cropperjs/css/cropper.css">

<script>
    /****************** Area/region selection related functions ******************/

    $(function() {
        $('#replace').click(function () {
            $('#browse').click();
        });
    });

    /**
     * Rounds the number into max two decimal points.
     * @param num
     * @return {number}
     */
    function round(num) {
        return Math.round((num + 0.00001) * 100) / 100;
    }

    /**
     * To be called when selection changed.
     * @param x
     * @param y
     * @param w
     * @param h
     */
    function setXywh(x, y, w, h) {
        areaX = x; areaY = y; areaWidth = w; areaHeight = h;
        $('.value-x').text(x);
        $('.value-y').text(y);
        $('.value-w').text(w);
        $('.value-h').text(h);
    }

    /**
     * Selects full page
     */
    function selectFullPage() {
        theCropper.setCropBoxData({
            left: 0, right: 0,
            width: theCropper.imageData.naturalWidth, height: theCropper.imageData.naturalHeight
        });
    }

    function createCropper(image, width, height){
        return new Cropper(image, {
            viewMode: 1,
            movable: false,
            zoomable: false,
            maxContainerHeight: height,
            maxContainerWidth: width,
            maxCanvasHeight: height,
            maxCanvasWidth: width,
            //background: false,
            crop: function(e) {
                var imgWidth = theCropper.imageData.naturalWidth;
                var imgHeight = theCropper.imageData.naturalHeight;
                setXywh(round(e.detail.x * 1.0 / imgWidth), round(e.detail.y * 1.0 / imgHeight),
                    round(e.detail.width * 1.0 / imgWidth), round(e.detail.height * 1.0 / imgHeight));
            },

            ready: function() {
                selectFullPage();
            }
        });
    }

    var image = document.getElementById('image');
    var theCropper = createCropper(image, 100, 200);

    $("input:file").change(function() {
        var oFReader = new FileReader();
        oFReader.readAsDataURL(this.files[0]);

        oFReader.onload = function (oFREvent) {
            var newImg = new Image();

            var imgSrc = this.result;
            newImg.src = imgSrc;

            newImg.onload = function() {
                theCropper.replace(imgSrc);
            };
        };
    });

</script>

<!-- For picture zoom in/out -->
<script src="https://yyx990803.github.io/zoomerang/zoomerang.js"></script>
<script>
    function enableZoom() {
        Zoomerang.config({
            maxWidth: window.innerWidth, // 400,
            maxHeight: window.innerHeight, // 400,
            bgColor: '#000',
            bgOpacity: .85,
            onClose: function(target) {
                target.style.transform = ''; // fixing origin missing bug
            }
        }).listen('.zoom');
    }
</script>


</body>
</html>